package com.epalmpay.service.trade.impl;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StreamUtils;
import org.springframework.web.multipart.MultipartFile;

import com.epalmpay.bean.TradeCheckOpBean;
import com.epalmpay.dto.datareport.TradeCheckedInDTO;
import com.epalmpay.dto.trade.TradeCheckInDTO;
import com.epalmpay.dto.trade.TradeCouponInfoDTO;
import com.epalmpay.entity.Page;
import com.epalmpay.entity.TradeOffline;
import com.epalmpay.entity.TradeOfflineAbandon;
import com.epalmpay.entity.TradecheckRecord;
import com.epalmpay.enumdef.BizEnum;
import com.epalmpay.exception.ApplicationException;
import com.epalmpay.mapper.TradeOfflineAbandonMapper;
import com.epalmpay.mapper.TradeOfflineMapper;
import com.epalmpay.mapper.TradecheckRecordMapper;
import com.epalmpay.service.trade.ITradeCheckService;
import com.epalmpay.util.DateUtil;
import com.epalmpay.util.PropertyCopyUtil;
import com.epalmpay.util.SysUtils;
import com.epalmpay.util.Tools;

@Service("tradeCheckService")
public class TradeCheckServiceImpl implements ITradeCheckService{

	 @Resource
	private TradecheckRecordMapper tradecheckRecordMapper;
	
	@Resource
	private	TradeOfflineMapper tradeOfflineMapper;
	
	@Resource
	private	TradeOfflineAbandonMapper tradeOfflineAbandonMapper;
	
	/**
	 * 保存未对账的文件
	 */
	@Value("unCheckTradeFilepath")
	private String unCheckTradeFilepath;
	/**
	 * 保存已经对账的文件
	 */
	@Value("checkedTradeFilepath")
	private String checkedTradeFilepath;
	
	@Override
	public String finishSaveTradeCheckFile(MultipartFile file) throws ApplicationException {
		
	        FileOutputStream out = null;
	        InputStream in = null;
	        try {
	            String name = file.getOriginalFilename();
	            in= file.getInputStream();
	            File fileDir = new File(unCheckTradeFilepath);
	            if (!fileDir.exists()) {
					fileDir.mkdirs();
				}
	            out = new FileOutputStream(new File(unCheckTradeFilepath, name)) ;
	            StreamUtils.copy(in, out);	          
	        } catch (IOException e) {
	            e.printStackTrace();
	            return "error";
	        }finally{
	        	if(null != in){
	        		try {
						in.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
	        	}
	        	if(null != out){
	        		try {
						out.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
	        	}
	        }
	        return "保存对账文件成功";
	}

	/**
     *
	 #有平台发过来的对账文件
	 unCheckTradeFilepath=/tmp/checkTradeFile/unckecked/
	 #保存解析后的对账文件
	 checkedTradeFilepath=/tmp/checkTradeFile/ckecked/
	 */
	@Override
	public void finishTradeCheck() {
		File checkTradeDir=new File(unCheckTradeFilepath);
	    File [] files=checkTradeDir.listFiles();
	    for(File checTradeFile : files){
	    	ArrayList<TradeOffline> tradeOfflines=finishResloveTrade(checTradeFile);
	    	finishTradeCheck(tradeOfflines);
	    	//将对账文件复制到已对账的文件里面
	    	String fileName=checTradeFile.getName();
	    	File newfile=new File(unCheckTradeFilepath, fileName);
	    	SysUtils.finishCopyFile(checTradeFile, newfile);
	    	//
	    	checTradeFile.delete();
	    }
	}

	/**
	 * 对账文件的内容解析成 交易流水
	 * @param checTradeFile
	 * @return
	 */
	private ArrayList<TradeOffline> finishResloveTrade(File checTradeFile) {
		ArrayList<TradeOffline> result=new ArrayList<TradeOffline>();
		return result;
	}

	/**
	 * 解析对账文件，对照交易流水
	 * @param tradeOfflines
	 */
	private void finishTradeCheck(ArrayList<TradeOffline> tradeOfflines) {
		
		
	}

	@Override
	public void finishAddToTradeRecord(TradeCheckInDTO tradeCheckInDTo) throws ApplicationException {
		 TradeOffline tradeOffline=tradeOfflineMapper.selectByPrimaryKey(tradeCheckInDTo.getTradeOfflineId());
		 tradeOffline.setCheckStatus(BizEnum.CheckRecordStatus.checked.getType());
		 tradeOfflineMapper.updateByPrimaryKeySelective(tradeOffline);
		  TradecheckRecord tradecheckRecord=new TradecheckRecord();
		  tradecheckRecord.setGmtCreate(new Date());
		  tradecheckRecord.setGmtModified(new Date());
		  tradecheckRecord.setGroupId(tradeOffline.getGroupId());
		  tradecheckRecord.setMome(tradeCheckInDTo.getUpdateUser()+"将如下交易改成了有效交易， 交易记录id"+tradeOffline.getId()+",订单号为:"+tradeOffline.getTerminalNo()+"的交易");
		  tradecheckRecord.setOperateType(1);
		  tradecheckRecord.setOperateUserId(tradeCheckInDTo.getUpdateUserId());
		  tradecheckRecord.setOperateUsername(tradeCheckInDTo.getUpdateUser());
		  tradecheckRecord.setTradeOfflineId(tradeOffline.getId());
		  tradecheckRecordMapper.insert(tradecheckRecord);
	}

	@Override
	public List<TradeCheckOpBean> tradeCheckOpRecordList(TradeCheckInDTO tradeCheckInDTo, Page page) throws ApplicationException{
        Map<String,Object> param=new HashMap<String,Object>();
		
		param.put("groupId",tradeCheckInDTo.getGroupId());
		param.put("jionEndDate",tradeCheckInDTo.getJionEndDate());
		param.put("jionStartDate",tradeCheckInDTo.getJionStartDate());
		int sumCount = tradecheckRecordMapper.selectCountByCondiction(param);
		page.setTotalResult(sumCount);
		if(sumCount<=0)
			return new ArrayList<TradeCheckOpBean>();
		
		param.put("limit", page.getShowCount());
		param.put("start", page.getShowCount()*(page.getCurrentPage()-1));
		return 	tradecheckRecordMapper.selectInfoByCondiction(param);
		
	}

	@Override
	public void finishAbandonTradeRecord(TradeCheckInDTO tradeCheckInDTo) throws ApplicationException {
	  TradeOffline tradeOffline=tradeOfflineMapper.selectByPrimaryKey(tradeCheckInDTo.getTradeOfflineId());
	  TradeOfflineAbandon  tradeOfflineAbandon=new TradeOfflineAbandon();
	  try {
		PropertyCopyUtil.copyProperties(tradeOffline, tradeOfflineAbandon);
	} catch (Exception e) {
		e.printStackTrace();
	}
	  TradeOfflineAbandon temp=  tradeOfflineAbandonMapper.selectByPrimaryKey(tradeOfflineAbandon.getId());
	  if(temp==null){
		  tradeOfflineAbandonMapper.insert(tradeOfflineAbandon);
	  }else{
		  tradeOfflineAbandonMapper.updateByPrimaryKey(tradeOfflineAbandon);
	  }
	  
	  //可能需要删除交易记录 ,并且删除相关连的记录
	  tradeOfflineAbandonMapper.deleteByPrimaryKey(tradeOffline.getId());
		
	  TradecheckRecord tradecheckRecord=new TradecheckRecord();
	  tradecheckRecord.setGmtCreate(new Date());
	  tradecheckRecord.setGmtModified(new Date());
	  tradecheckRecord.setGroupId(tradeOffline.getGroupId());
	  tradecheckRecord.setMome(tradeCheckInDTo.getUpdateUser()+"废弃了 交易记录id"+tradeOffline.getId()+",订单号为:"+tradeOffline.getTerminalNo()+"的交易");
	  tradecheckRecord.setOperateType(2);
	  tradecheckRecord.setOperateUserId(tradeCheckInDTo.getUpdateUserId());
	  tradecheckRecord.setOperateUsername(tradeCheckInDTo.getUpdateUser());
	  tradecheckRecord.setTradeOfflineId(tradeOffline.getId());
	  tradecheckRecordMapper.insert(tradecheckRecord);
	}

	
    /**通过id获取数据
     * @return
     * @throws Exception
     */
    @Override
    public TradeOffline offlinefindById(TradeOffline offline)throws ApplicationException{

        //查询交易表信息
        TradeOffline tradeOffline = tradeOfflineMapper.selectCheckOfflineById(offline.getId());

        //查询会员信息和会员等级
        if (offline.getMemberId() != null){
            Map<String, Object> map1 = tradeOfflineMapper.selectMemberInfoById(offline.getMemberId());
            if (map1 != null) {
                tradeOffline.setMemberId((Long) map1.get("memberId"));
                tradeOffline.setCardNo((String) map1.get("cardNo"));
                tradeOffline.setMemberName((String) map1.get("memberName"));
                tradeOffline.setGradeName((String) map1.get("gradeName"));
                tradeOffline.setFromName((String) map1.get("fromName"));
                if (!tradeOffline.getPayerId().equals(offline.getMemberId())){
                    tradeOffline.setReceiverName(tradeOffline.getPayerName());
                }
            }
        }else{
            Map<String, Object> map2 = tradeOfflineMapper.selectMemberInfoById(tradeOffline.getPayerId());
            if (map2 != null) {
                tradeOffline.setMemberId((Long) map2.get("memberId"));
                tradeOffline.setCardNo((String) map2.get("cardNo"));
                tradeOffline.setMemberName((String) map2.get("memberName"));
                tradeOffline.setGradeName((String) map2.get("gradeName"));
                tradeOffline.setFromName((String) map2.get("fromName"));
            }
        }


        //查询消费返现
        /*TradeOffline tradeOffline1 = tradeOfflineMapper.selectOfflineBackAmtById(offline.getId());
        if (tradeOffline1 != null){
            tradeOffline.setBackAmount(tradeOffline1.getOrderAmount());
        }*/
		TradeOffline tradeOffline1 =null;
		if (offline.getMemberId() != null) {
			tradeOffline1 = tradeOfflineMapper.getTradeDataByRelatedTradeOfflineId(offline.getId(), offline.getMemberId().toString());
//        TradeOffline tradeOffline1 = tradeOfflineMapper.selectOfflineBackAmtById(offline.getId());
		}else{
			tradeOffline1 = tradeOfflineMapper.getTradeDataByRelatedTradeOfflineId(offline.getId(), tradeOffline.getPayerId().toString());
		}
		if (tradeOffline1 != null){
			tradeOffline.setBackAmount(tradeOffline1.getOrderAmount());
		}

        //查询优惠券
        int count = tradeOfflineMapper.selectOfflineCouponCountById(offline.getId());
        if (count>0){
            tradeOffline.setCouponCount(count);
            List<Map<String, Object>> coupons = tradeOfflineMapper.selectOfflineCouponsById(offline.getId());
            if (coupons != null){
                List<TradeCouponInfoDTO> couponInfos = new ArrayList<>();
                for (int i = 0; i <coupons.size(); i++) {
                    TradeCouponInfoDTO couponInfoDTO = new TradeCouponInfoDTO();
                    couponInfoDTO.setCouponName((String) coupons.get(i).get("couponName"));
                    couponInfoDTO.setCouponValue((Integer) coupons.get(i).get("couponValue"));
                    couponInfoDTO.setCouponType((Integer) coupons.get(i).get("couponType"));
                    couponInfos.add(couponInfoDTO);
                }
                tradeOffline.setCouponInfo(couponInfos);

            }
        }

        return tradeOffline;
    }


    /**通过id获取数据
     * @return
     * @throws Exception
     */
    @Override
    public TradeOffline abandonOfflinefindById(TradeOffline offline)throws ApplicationException{

        //查询交易表信息
        TradeOffline tradeOffline = tradeOfflineMapper.selectCheckOfflineById(offline.getId());

        //查询会员信息和会员等级
        if (offline.getMemberId() != null){
            Map<String, Object> map1 = tradeOfflineMapper.selectMemberInfoById(offline.getMemberId());
            if (map1 != null) {
                tradeOffline.setMemberId((Long) map1.get("memberId"));
                tradeOffline.setCardNo((String) map1.get("cardNo"));
                tradeOffline.setMemberName((String) map1.get("memberName"));
                tradeOffline.setGradeName((String) map1.get("gradeName"));
                tradeOffline.setFromName((String) map1.get("fromName"));
                if (!tradeOffline.getPayerId().equals(offline.getMemberId())){
                    tradeOffline.setReceiverName(tradeOffline.getPayerName());
                }
            }
        }else{
            Map<String, Object> map2 = tradeOfflineMapper.selectMemberInfoById(tradeOffline.getPayerId());
            if (map2 != null) {
                tradeOffline.setMemberId((Long) map2.get("memberId"));
                tradeOffline.setCardNo((String) map2.get("cardNo"));
                tradeOffline.setMemberName((String) map2.get("memberName"));
                tradeOffline.setGradeName((String) map2.get("gradeName"));
                tradeOffline.setFromName((String) map2.get("fromName"));
            }
        }


        //查询消费返现
		TradeOffline tradeOffline1 =null;
		if (offline.getMemberId() != null) {
			 tradeOffline1 = tradeOfflineMapper.getTradeDataByRelatedTradeOfflineId(offline.getId(), offline.getMemberId().toString());
//        TradeOffline tradeOffline1 = tradeOfflineMapper.selectOfflineBackAmtById(offline.getId());
		}else{
			tradeOffline1 = tradeOfflineMapper.getTradeDataByRelatedTradeOfflineId(offline.getId(), tradeOffline.getPayerId().toString());
		}
        if (tradeOffline1 != null){
            tradeOffline.setBackAmount(tradeOffline1.getOrderAmount());
        }

        //查询优惠券
        int count = tradeOfflineMapper.selectOfflineCouponCountById(offline.getId());
        if (count>0){
            tradeOffline.setCouponCount(count);
            List<Map<String, Object>> coupons = tradeOfflineMapper.selectOfflineCouponsById(offline.getId());
            if (coupons != null){
                List<TradeCouponInfoDTO> couponInfos = new ArrayList<>();
                for (int i = 0; i <coupons.size(); i++) {
                    TradeCouponInfoDTO couponInfoDTO = new TradeCouponInfoDTO();
                    couponInfoDTO.setCouponName((String) coupons.get(i).get("couponName"));
                    couponInfoDTO.setCouponValue((Integer) coupons.get(i).get("couponValue"));
                    couponInfoDTO.setCouponType((Integer) coupons.get(i).get("couponType"));
                    couponInfos.add(couponInfoDTO);
                }
                tradeOffline.setCouponInfo(couponInfos);

            }
        }

        return tradeOffline;
    }
    
	@Override
	public List<TradeOfflineAbandon> listOfflineRecords(TradeCheckedInDTO offlineRecordInDTO, Page page) throws ApplicationException {
		    Map<String,Object> param=new HashMap<String,Object>();	
			param.put("groupId",offlineRecordInDTO.getGroupId());
			param.put("receiverName",offlineRecordInDTO.getReceiverName());
			param.put("transactionType",offlineRecordInDTO.getTransactionType());
			param.put("payType",offlineRecordInDTO.getPayType());
			param.put("orderId",offlineRecordInDTO.getOrderId()); 
        
         
         if (!Tools.isEmpty(offlineRecordInDTO.getJoinStart())) {
        	 param.put("joinStart",offlineRecordInDTO.getJoinStart()); 
          
         }
         if (!Tools.isEmpty(offlineRecordInDTO.getJoinEnd())) {
        	 param.put("joinEnd",offlineRecordInDTO.getJoinEnd()); 
         }
         if(offlineRecordInDTO.getSubType()!=null){
        	 param.put("subType",offlineRecordInDTO.getSubType()); 
         }
         
         int sumCount = tradeOfflineAbandonMapper.tradeOfflineAbandonlistCount(param);
 		page.setTotalResult(sumCount);
 		if(sumCount<=0)
 			return new ArrayList<TradeOfflineAbandon>();
 		
 		param.put("limit", page.getShowCount());
 		param.put("start", page.getShowCount()*(page.getCurrentPage()-1));

         List<TradeOfflineAbandon> tradeOfflineList = tradeOfflineAbandonMapper.tradeOfflineAbandon(param);
         return tradeOfflineList;
	}
	
}
